package marvin.webapp.audio.subscription;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;

import marvin.webapp.audio.rtp.RTPServer;
import marvin.webapp.audio.util.MagicTool;
import marvin.webapp.audio.util.PushNotifier;
import marvin.webapp.exception.MarvinException;

public class ClientHandler extends Thread{

	private SubscriptionServer subscriptionServer;
	private Socket soc;
	private String clientSentence;
	private String clientName;
	private String currentFilePath;

	private int sound, rtpBasePort;
	private BufferedReader inFromClient;
	private PrintStream outToClient;
	
	private boolean run = false;
	private List<File> playList;
	private RTPServer srv;

	public ClientHandler(Socket clientSocket, SubscriptionServer subscriptionServer, int rtpBasePort) {
		playList = new ArrayList<File>();
		this.subscriptionServer = subscriptionServer;
		this.rtpBasePort = rtpBasePort;
		soc = clientSocket;
		clientName = soc.getInetAddress().getHostAddress();
		sound = 50;
		int rtpPort = 6666;
		srv = new RTPServer(soc.getInetAddress().getHostAddress(), rtpPort, this.rtpBasePort, this);
		try {
			inFromClient = new BufferedReader(new InputStreamReader(soc.getInputStream()));
			outToClient = new PrintStream(soc.getOutputStream());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void run() {
		try {
			run = true;

			while(run){
				clientSentence = inFromClient.readLine();
				System.out.println(clientName + " sends: " +clientSentence);
				if(clientSentence == null || clientSentence.equals("disconnect")){
					subscriptionServer.removeClient(this);
					if(srv != null)
						srv.stopStreaming();
					run = false;
				} else if(clientSentence.startsWith("id:")){
					String[] fragments = clientSentence.split(":");
					clientName = fragments[1];
					PushNotifier.sendNotification("Client connection", "Client gives its id");
				} else if(clientSentence.equals("end of media")){
					srv.playNext();
				}
			}
		} 
		catch (IOException e) {
			subscriptionServer.removeClient(this);
		} catch (MarvinException e) {
			e.printStackTrace();
		}
	}
	
	public void streamFile(File file) throws IOException, InterruptedException, MarvinException{
		if(srv != null)
			srv.stopStreaming();
		
		if(file.isFile()){
			List<File> f = new ArrayList<File>();
			f.add(file);
			srv.streamFiles(f);
		}
		else if (file.isDirectory()){
			List<File> files = MagicTool.getOnlyFiles(file);
			srv.streamFiles(files);
		}		
	}
	
	public void stream(URI uri) throws IOException {
		if(srv != null)
			srv.stopStreaming();
		
		srv.stream(uri);
	}
	
	public void sentToClient(String msg){
		outToClient.println(msg);
	}
	
	public void stopReading(){
		run = false;
	}
	
	public void bufferURIs(List<String> radioURLs) {
		for(String uri: radioURLs){
			sentToClient("buffer:"+"http://"+uri);
		}
	}

	public String getClientSentence() {
		return clientSentence;
	}

	public String getClientName() {
		return clientName;
	}

	public int getSound() {
		return sound;
	}

	public void setSound(int sound) {
		this.sound = sound;
	}

	public RTPServer getSrv() {
		return srv;
	}

	public void setCurrentFilePath(String absolutePath) {
		currentFilePath = absolutePath;
	}

	public String getCurrentFilePath() {
		return currentFilePath;
	}

	public List<File> getPlayList() {
		return playList;
	}

	public void setPlayList(List<File> playList) {
		this.playList = playList;
	}

	public void streamPlayList() throws IOException, MarvinException {
		if(playList != null && !playList.isEmpty()){
			if(srv != null)
				srv.stopStreaming();
			srv.streamFiles(playList);
		} else
			throw new MarvinException("Play list is empty");
	}
}
